--[[
local origPrint = print
print = function(...)
	origPrint(...)
	local str = ""
	for i = 1, select('#', ...) do
		if i ~= 1 then
			str = str .. "\t"
		end
		str = str .. tostring(select(i, ...))
	end
	love.filesystem.append( "log.txt", str .. "\r\n" )
end
--]]

local love = _G.love
network = require( "network.network" )
config = require( "config" )
game = require( "game" )
lobby = require( "lobby" )
map = require( "map" )
if not DEDICATED then
	stats = require( "stats" )
	ui = require( "lib/punchUI" )
	menu = require( "menu" )
	images = require( "images" )	-- loads all images.
	chat = require( "chat" )
	Sounds = require("sounds")
end
utility = require( "utility" )		-- helper functions
require( "callbacks" )		-- helper functions

server = nil
client = nil

STATE = "Menu"

MAX_PLAYERS = 16
PORT = 3410
MAIN_SERVER_URL = "http://www.formauri.es/personal/AffairMainServer"
GAME_ID = "GridCars"

if not DEDICATED then

function love.load( args )

	config.load()

	images:load()	-- preload all images
	Sounds:load()
	chat:init()
	lobby:init()
	menu:init()
	game:init()
	map:load()

	menu:show()

	--[[local startServer = false
	local startClient = false
	if args[2] == "client" then
		startClient = true
	elseif args[2] == "server" then
		startServer = true
	end
	if startServer then
		-- Start a server with a maximum of 16 users.
		server = network:startServer( MAX_PLAYERS, PORT )
		-- Connect to the server.
		client = network:startClient( 'localhost', PLAYERNAME, PORT )

		-- set server callbacks:
		setServerCallbacks( server )

		-- set client callbacks:
		setClientCallbacks( client )

		lobby:show()
	elseif startClient then
		if args[3] then
			client = network:startClient( args[3], PLAYERNAME, PORT )
			setClientCallbacks( client )
		else
			print( "Error. To start as client, you should give the address as the argument after 'client'." )
		end
	end]]

	--love.graphics.setBackgroundColor(25,25,25,255)
	love.graphics.setBackgroundColor( 20,80,20,255)
end

function love.update( dt )
	network:update( dt )
	if STATE == "Game" then
		game:update( dt )
		chat:update( dt )
	elseif STATE == "Lobby" then
		lobby:update( dt )
		chat:update( dt )
	elseif STATE == "Menu" then
		menu:update( dt )
	end
	ui:update( dt )
	ui:mousemoved( love.mouse.getPosition() )
end

function love.keypressed( key, unicode )
	--chat:keypressed( key )
	if chat.active then
		chat:keypressed( key )
	elseif not ui:keypressed( key, unicode ) then
		map:keypressed( key )
		chat:keypressed( key )
	end
end

function love.textinput( letter )
	--chat:textinput( letter )
	if chat.active then
		chat:textinput( letter )
	elseif (not ui:textinput( letter )) then
	end
end

function love.mousepressed( x, y, button )
	if button == 1 then button = "l" end
	if button == 2 then button = "r" end
	if button == 3 then button = "m" end
	if ui:mousepressed( x, y, button ) then
		return
	end
	map:mousepressed( x, y, button )
	if STATE == "Game" then
		game:mousepressed( x, y, button )
	end
end

function love.wheelmoved(x, y)
  local mx, my = love.mouse.getPosition(x, y)
  local limit, btn = y, "wu"
  if y < 0 then
    limit, btn = -y, "wd"
  end
  for i = 1, limit do
    _G.love.mousepressed(mx, my, btn)
  end
end

function love.draw()

	if STATE == "Game" then
		game:draw()
	elseif STATE == "Lobby" then
		lobby:draw()
	elseif STATE == "Menu" then
		menu:draw()
	end

	if STATE == "Game" or STATE == "Lobby" then
		chat:draw()
	end

	ui:draw()

end

else

-- Dedicated server
local socket = require("socket")

dedicated = {
	currentMapName = nil,
	mapCycleID = 0
}

config.load()

--lobby:init()
--game:init()
map:load()

function dedicated:startServer()
	local err
	server, err = network:startServer( MAX_PLAYERS, PORT )

	if server then
		-- set client callbacks:
		setServerCallbacks( server )
		lobby:show()

		updateAdvertisementInfo()
		network.advertise:setURL( MAIN_SERVER_URL )
		network.advertise:setID( GAME_ID )

		network.advertise:start( server, "both" )

	else
		-- If I can't start a server for some reason, let user know and exit:
		print("ERROR: Could not start server:")
		print( "\t", err)
		os.exit()
	end
end

function dedicated:update( dt )

	if STATE == "Lobby" then

		-- Wait for at least one user:
		if server:getNumUsers() > 0 then
			-- Check if all clients are ready and if so start game
			if not self.postMatchLocked then
				if lobby:attemptGameStart() then
					game:show()
				end
			end
		end
	elseif STATE == "Game" then
		-- Let's hope it never gets below 0... :P
		if game:getNumUsersPlaying() <= 0 then
			game:sendBackToLobby()
		end
	end
end

-- Show the old map for a set period of time.
function dedicated:postMatchLock()
	self.postMatchLocked = true
end

function getDirectoryItems( dir )
	return love.filesystem.getDirectoryItems(dir)
end

function dedicated:loadMapCycle()
	MAP_CYCLE = config.getValue( "MAP_CYCLE" )
	MAP_CYCLE_TBL = {}
	if MAP_CYCLE then
		for file in MAP_CYCLE:gmatch( "([^%s,]+)%s*,?%s*" ) do
			table.insert( MAP_CYCLE_TBL, file )
		end
	end

	-- Look for invalid file names ...
	local invalidFiles = {}
	for k = #MAP_CYCLE_TBL,1,-1 do -- iterate backwards because of the table.remove call
		local filename = MAP_CYCLE_TBL[k]
		-- Try to open the file, to see if it exists:
		local f = love.filesystem.open( "maps/" .. filename )
		if not f then
	--		table.insert( invalidFiles, k )
			table.remove( MAP_CYCLE_TBL, k )
		else
			f:close()
		end
	end
end

function dedicated:chooseMap()

	self:loadMapCycle()

	local foundMapFromMapCycle = nil
	if #MAP_CYCLE_TBL > 0 then
		if MAP_CYCLE_TBL[self.mapCycleID+1] then
			self.currentMapName = MAP_CYCLE_TBL[self.mapCycleID+1]
			self.mapCycleID = self.mapCycleID + 1
		else
			self.currentMapName = MAP_CYCLE_TBL[1]
			self.mapCycleID = 1
		end
		foundMapFromMapCycle = true
	end

	if not foundMapFromMapCycle then
		print("No map cycle found. Will play all maps in maps/ subfolder:")
		local files = getDirectoryItems( "maps/" )

		if #files < 1 then
			return
		end

		-- first map?
		if self.currentMapName == nil then
			self.currentMapName = files[1]
		else
			for k, f in ipairs(files) do
				if f == self.currentMapName then
					if files[k+1] then
						self.currentMapName = files[k+1]
					else
						self.currentMapName = files[1]
					end
					break
				end
			end
		end
	else
		print("Map cycle:")
		for k, file in ipairs( MAP_CYCLE_TBL ) do
			if k == self.mapCycleID then
				print( "\t>" .. file )
			else
				print( "\t " .. file )
			end
		end
	end

	-- Choose this map, load it and send it to all clients:
	lobby:chooseMap( self.currentMapName )
	self.postMatchLocked = false
end

-- Call the function to start the server right at startup
dedicated:startServer()

function love.update(dt)
	network:update( dt )
	if STATE == "Game" then
		game:update( dt )
	elseif STATE == "Lobby" then
		lobby:update( dt )
	end

	dedicated:update( dt )

	love.timer.sleep( 0.05 )
end

function love.quit()
	if network and network.advertise then
		network.advertise:stop()
		love.timer.sleep(1)
	end
end

end

love = require('compat')
